package com.hkrt.demo.zip;

import java.io.*;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

/**
 * @author Surpass
 * @Package com.hkrt.demo.zip
 * @Description: 压缩包解压保持原有的目录
 * @date 2020/10/17 11:39
 */
public class MultipleFilesUnpackThe {

    private static OutputStream outputStream;
    private static InputStream inputStream;
    private static ZipInputStream bi;

    private static String ZipPath = "C:\\Users\\Surpass\\Desktop\\Bypass.zip";

    public static void main(String[] args) {

        try {
            File zipFile = new File(ZipPath);
            //压缩包的名字，不包含后缀  .zip
            String zipName = zipFile.getName().substring(0, zipFile.getName().indexOf("."));
            //压缩包所在的路径
            String zipFileParentPath = zipFile.getParent();

            //输入流读取压缩包
            inputStream = new FileInputStream(ZipPath);
            //包装流
            bi = new ZipInputStream(inputStream);
            ZipEntry entry = null;
            //按照压缩结构解压
            while ( (entry = bi.getNextEntry())!=null){
                if (entry.isDirectory()) {
                    //空文件夹，直接创建  压缩包路径+压缩包名字+空文件夹路径
                    File file = new File(zipFileParentPath+"\\"+zipName+"\\"+entry);
                    file.mkdirs();
                }else {
                    //获取文件在压缩包内的路径
                    String entryPath = entry.getName().substring(0,entry.getName().lastIndexOf("\\"));

                    //为存放的路径创建文件夹
                    File file = new File(zipFileParentPath+"\\"+zipName+"\\"+entryPath);
                    if (!file.exists()) {
                        file.mkdirs();
                    }
                    outputStream = new FileOutputStream(zipFileParentPath+"\\"+zipName+"\\"+ entry.getName());
                }
                //写文件
                byte[] bytes = new byte[1024];
                int len = 0;
                while ((len = bi.read(bytes))!=-1){
                    outputStream.write(bytes,0,len);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if (bi!=null){
                    bi.closeEntry();
                    bi.close();
                }
                if (inputStream!=null){
                    inputStream.close();
                }
                if (outputStream!=null){
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void multipleFilesUnpackThe(String[] args) {

        try {
            ZipFile zipFile = new ZipFile(ZipPath, Charset.forName("GBK"));
            //压缩包的名字，不包含后缀  .zip
            String zipName = zipFile.getName().substring(0, zipFile.getName().indexOf("."));
            //压缩包所在的路径
            String zipFileParentPath = zipFile.getName().substring(0,zipFile.getName().lastIndexOf("\\"));

            Enumeration<? extends ZipEntry> entries = zipFile.entries();

            while (entries.hasMoreElements()) {
                ZipEntry entry = entries.nextElement();
                if (entry.isDirectory()) {
                    //空文件夹，直接创建  压缩包路径+压缩包名字+空文件夹路径
                    File file = new File(zipFileParentPath+"\\"+zipName+"\\"+entry);
                    file.mkdirs();
                }else {
                    //获取文件在压缩包内的路径
                    String entryPath = entry.getName().substring(0,entry.getName().lastIndexOf("\\"));

                    //为存放的路径创建文件夹
                    File file = new File(zipFileParentPath+"\\"+zipName+"\\"+entryPath);
                    if (!file.exists()) {
                        file.mkdirs();
                    }
                    outputStream = new FileOutputStream(zipFileParentPath+"\\"+zipName+"\\"+ entry.getName());
                }
                //写文件
                byte[] bytes = new byte[1024];
                int len = 0;
                while ((len = bi.read(bytes))!=-1){
                    outputStream.write(bytes,0,len);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if (bi!=null){
                    bi.closeEntry();
                    bi.close();
                }
                if (inputStream!=null){
                    inputStream.close();
                }
                if (outputStream!=null){
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
